spb/satelliteindex
Public
TypeScript 66.5%
Python 30.9%
JavaScript 1.4%
CSS 0.7%
1import { ImageResponse } from 'next/og';2import { api, safe } from '@/lib/api';3import { fmtInt } from '@/lib/format';45export const alt = 'Constellation summary — SatelliteIndex';6export const size = { width: 1200, height: 630 };7export const contentType = 'image/png';89const ORBIT_HEX: Record<string, string> = { LEO: '#38d3ff', MEO: '#8f7dff', GEO: '#f5b544', HEO: '#ff7ab6' };1011export default async function Image({ params }: { params: Promise<{ slug: string }> }) {12 const { slug } = await params;13 const res = await safe(api.constellation(slug));14 const d = res?.data ?? null;15 const orbit = d?.orbit_class ?? 'MIXED';16 const color = ORBIT_HEX[orbit] ?? '#7c869e';1718 return new ImageResponse(19 (20 <div style={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'space-between', padding: 64, background: 'linear-gradient(135deg, #060912 0%, #0b1020 60%, #111830 100%)', color: '#eaf0ff', fontFamily: 'sans-serif' }}>21 <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>22 <div style={{ display: 'flex', alignItems: 'center', gap: 14, fontSize: 26, letterSpacing: 4, textTransform: 'uppercase', color: '#a3aec8' }}>23 <div style={{ width: 14, height: 14, borderRadius: 999, background: '#38d3ff' }} />24 <div>SatelliteIndex · Constellation</div>25 </div>26 <div style={{ display: 'flex', padding: '8px 18px', borderRadius: 8, border: `2px solid ${color}`, color, fontSize: 28, fontWeight: 700 }}>{orbit}</div>27 </div>2829 {d ? (30 <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>31 <div style={{ fontSize: d.name.length > 28 ? 60 : 84, fontWeight: 700, letterSpacing: -2, lineHeight: 1 }}>{d.name}</div>32 <div style={{ fontSize: 34, color: '#a3aec8' }}>{`${d.operator_name ?? 'Operator unavailable'}${d.country_name ? ` · ${d.country_name}` : ''}`}</div>33 </div>34 ) : (35 <div style={{ fontSize: 72, fontWeight: 700 }}>Constellation</div>36 )}3738 <div style={{ display: 'flex', gap: 56, borderTop: '1px solid rgba(160,180,230,0.28)', paddingTop: 28 }}>39 {[40 { label: 'Active satellites', value: d ? fmtInt(d.active) : '—', c: '#38d17f' },41 { label: 'Total launched', value: d ? fmtInt(d.total) : '—', c: '#eaf0ff' },42 { label: 'Launched 365 d', value: d ? fmtInt(d.launched_last_365d) : '—', c: '#eaf0ff' },43 { label: 'Launches', value: d ? fmtInt(d.launches) : '—', c: '#eaf0ff' },44 ].map((k) => (45 <div key={k.label} style={{ display: 'flex', flexDirection: 'column' }}>46 <div style={{ fontSize: 20, letterSpacing: 3, textTransform: 'uppercase', color: '#6b7694' }}>{k.label}</div>47 <div style={{ fontSize: 56, fontWeight: 700, color: k.c, marginTop: 6 }}>{k.value}</div>48 </div>49 ))}50 </div>51 </div>52 ),53 size,54 );55}56